home *** CD-ROM | disk | FTP | other *** search
/ Acorn User: China / Acorn User China CD-ROM (UK) (Disc A) / Acorn User China CD-ROM (UK) (Disc A).bin / DEMON / MISC / NETLITE2.ARC / NET / c / TCPIN < prev    next >
Encoding:
Text File  |  1993-03-15  |  31.3 KB  |  805 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  */
  4.  
  5. #include <stdlib.h>
  6. #include "global.h"
  7. #include "timer.h"
  8. #include "mbuf.h"
  9. #include "netuser.h"
  10. #include "internet.h"
  11. #include "tcp.h"
  12. #include "icmp.h"
  13. #include "iface.h"
  14. #include "ip.h"
  15.  
  16. static void reset(int32, int32, char, int16, struct tcp *);
  17. static void update(struct tcb *, struct tcp *);
  18. static int  in_window(struct tcb *, int32);
  19. static void proc_syn(struct tcb *, char, struct tcp *);
  20. static void add_reseq(struct tcb *, char, struct tcp *, struct mbuf *, int16);
  21. static void get_reseq(struct tcb *, char *, struct tcp *, struct mbuf **, int16 *);
  22. static int trim(struct tcb *, struct tcp *, struct mbuf **, int16 *); 
  23.  
  24. struct tcp_stat tcp_stat;
  25.  
  26. /* This function is called from IP with the IP header in machine byte order,
  27.  * along with a mbuf chain pointing to the TCP header.
  28.  */
  29. void tcp_input(struct mbuf *bp, char protocol,int32 source,
  30.                int32 dest, char tos, int16 length, char rxbroadcast)
  31. {
  32.         register struct tcb *tcb;       /* TCP Protocol control block */
  33.         struct tcp seg;                 /* Local copy of segment header */
  34.         struct connection conn;         /* Local copy of addresses */
  35.         struct pseudo_header ph;        /* Pseudo-header for checksumming */
  36.         int hdrlen;                     /* Length of TCP header */
  37.  
  38.         if(bp == NULLBUF)
  39.                 return;
  40.  
  41.         if(rxbroadcast){
  42.                 /* Any TCP packet arriving as a broadcast is
  43.                  * to be completely IGNORED!!
  44.                  */
  45.                 tcp_stat.bdcsts++;
  46.                 free_p(bp);
  47.                 return;
  48.         }
  49.         ph.source = source;
  50.         ph.dest = dest;
  51.         ph.protocol = protocol;
  52.         ph.length = length;
  53.         if(cksum(&ph,bp,length) != 0){
  54.                 /* Checksum failed, ignore segment completely */
  55.                 tcp_stat.checksum++;
  56.                 free_p(bp);
  57.                 return;
  58.         }
  59.         /* Form local copy of TCP header in host byte order */
  60.         if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  61.                 /* TCP header is too small */
  62.                 tcp_stat.runt++;
  63.                 free_p(bp);
  64.                 return;
  65.         }
  66.         length -= hdrlen;
  67.  
  68.         /* Fill in connection structure and find TCB */
  69.         conn.local.address = dest;
  70.         conn.local.port = seg.dest;
  71.         conn.remote.address = source;
  72.         conn.remote.port = seg.source;
  73.         
  74.         if((tcb = lookup_tcb(&conn)) == NULLTCB){
  75.                 struct tcb *ntcb;
  76.  
  77.                 /* Check that this segment carries a SYN, and that
  78.                  * there's a LISTEN on this socket with
  79.                  * unspecified source address and port
  80.                  */
  81.                 conn.remote.address = 0;
  82.                 conn.remote.port = 0;
  83.                 if(!(seg.flags & SYN) || (tcb = lookup_tcb(&conn)) == NULLTCB){
  84.                         /* No unspecified LISTEN either, so reject */
  85.                         free_p(bp);
  86.                         reset(source,dest,tos,length,&seg);
  87.                         return;
  88.                 }
  89.                 /* We've found an server listen socket, so clone the TCB */
  90.                 if(tcb->flags & CLONE){
  91.                         if((ntcb = (struct tcb *)malloc(sizeof (struct tcb))) == NULLTCB){
  92.                                 free_p(bp);
  93.                                 /* This may fail, but we should at least try */
  94.                                 reset(source,dest,tos,length,&seg);
  95.                                 return;
  96.                         }
  97.                         *ntcb = *tcb;
  98.                         tcb = ntcb;
  99.                         tcb->timer.arg = (char *)tcb;
  100.                 } else
  101.                         unlink_tcb(tcb);        /* It'll be put back on later */
  102.  
  103.                 /* Stuff the foreign socket into the TCB */
  104.                 tcb->conn.remote.address = source;
  105.                 tcb->conn.remote.port = seg.source;
  106.  
  107.                 /* NOW put on right hash chain */
  108.                 link_tcb(tcb);
  109.         }
  110.         /* Do unsynchronized-state processing (p. 65-68) */
  111.         switch(tcb->state){
  112.         case CLOSED:
  113.                 free_p(bp);
  114.                 reset(source,dest,tos,length,&seg);
  115.                 return;
  116.         case LISTEN:
  117.                 if(seg.flags & RST){
  118.                         free_p(bp);
  119.                         return;
  120.                 }
  121.                 if(seg.flags & ACK){
  122.                         free_p(bp);
  123.                         reset(source,dest,tos,length,&seg);
  124.                         return;
  125.                 }
  126.                 if(seg.flags & SYN){
  127.                         /* (Security check is bypassed) */
  128.                         /* page 66 */
  129.                         tcp_stat.conin++;
  130.                         proc_syn(tcb,tos,&seg);
  131.                         send_syn(tcb);
  132.                         setstate(tcb,SYN_RECEIVED);             
  133.                         if(length != 0 || (seg.flags & FIN)) {
  134.                                 break;          /* Continue processing if there's more */
  135.                         }
  136.                         tcp_output(tcb);
  137.                 }
  138.                 free_p(bp);     /* Unlikely to get here directly */
  139.                 return;
  140.         case SYN_SENT:
  141.                 if(seg.flags & ACK){
  142.                         if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  143.                                 free_p(bp);
  144.                                 reset(source,dest,tos,length,&seg);
  145.                                 return;
  146.                         }
  147.                 }
  148.                 if(seg.flags & RST){    /* p 67 */
  149.                         if(seg.flags & ACK){
  150.                                 /* The ack must be acceptable since we just checked it.
  151.                                  * This is how the remote side refuses connect requests.
  152.                                  */
  153.                                 close_self(tcb,RESET);
  154.                         }
  155.                         free_p(bp);
  156.                         return;
  157.                 }
  158.                 /* (Security check skipped here) */
  159.                 /* Check incoming precedence; it must match if there's an ACK */
  160.                 if((seg.flags & ACK) && PREC(tos) != PREC(tcb->tos)){
  161.                         free_p(bp);
  162.                         reset(source,dest,tos,length,&seg);
  163.                         return;
  164.                 }
  165.                 if(seg.flags & SYN){
  166.                         proc_syn(tcb,tos,&seg);
  167.                         if(seg.flags & ACK){
  168.                                 /* Our SYN has been acked, otherwise the ACK
  169.                                  * wouldn't have been valid.
  170.                                  */
  171.                                 update(tcb,&seg);
  172.                                 setstate(tcb,ESTABLISHED);
  173.                         } else {
  174.                                 setstate(tcb,SYN_RECEIVED);
  175.                         }
  176.                         if(length != 0 || (seg.flags & FIN)) {
  177.                                 break;          /* Continue processing if there's more */
  178.                         }
  179.                         tcp_output(tcb);
  180.                 } else {
  181.                         free_p(bp);     /* Ignore if neither SYN or RST is set */
  182.                 }
  183.                 return;
  184.         }
  185.         /* We reach this point directly in any synchronized state. Note that
  186.          * if we fell through from LISTEN or SYN_SENT processing because of a
  187.          * data-bearing SYN, window trimming and sequence testing "cannot fail".
  188.          */
  189.  
  190.         /* Trim segment to fit receive window. */
  191.         if(trim(tcb,&seg,&bp,&length) == -1){
  192.                 /* Segment is unacceptable */
  193.                 if(!(seg.flags & RST)){
  194.                         tcb->flags |= FORCE;
  195.                         tcp_output(tcb);
  196.                 }
  197.                 return;
  198.         }
  199.         /* If segment isn't the next one expected, and there's data
  200.          * or flags associated with it, put it on the resequencing
  201.          * queue, ACK it and return.
  202.          *
  203.          * Processing the ACK in an out-of-sequence segment without
  204.          * flags or data should be safe, however.
  205.          */
  206.         if(seg.seq != tcb->rcv.nxt
  207.          && (length != 0 || (seg.flags & (SYN|FIN)) )){
  208.                 add_reseq(tcb,tos,&seg,bp,length);
  209.                 tcb->flags |= FORCE;
  210.                 tcp_output(tcb);
  211.                 return;
  212.         }
  213.         /* This loop first processes the current segment, and then
  214.          * repeats if it can process the resequencing queue.
  215.          */
  216.         for(;;){
  217.                 /* We reach this point with an acceptable segment; all data and flags
  218.                  * are in the window, and the starting sequence number equals rcv.nxt
  219.                  * (p. 70)
  220.                  */     
  221.                 if(seg.flags & RST){
  222.                         if(tcb->state == SYN_RECEIVED
  223.                          && !(tcb->flags & (CLONE|ACTIVE))){
  224.                                 /* Go back to listen state only if this was
  225.                                  * not a cloned or active server TCB
  226.                                  */
  227.                                 setstate(tcb,LISTEN);
  228.                         } else {
  229.                                 close_self(tcb,RESET);
  230.                         }
  231.                         free_p(bp);
  232.                         return;
  233.                 }
  234.                 /* (Security check skipped here) p. 71 */
  235.                 /* Check for precedence mismatch or erroneous extra SYN */
  236.                 if(PREC(tos) != PREC(tcb->tos) || (seg.flags & SYN)){
  237.                         free_p(bp);
  238.                         reset(source,dest,tos,length,&seg);
  239.                         return;
  240.                 }
  241.                 /* Check ack field p. 72 */
  242.                 if(!(seg.flags & ACK)){
  243.                         free_p(bp);     /* All segments after synchronization must have ACK */
  244.                         return;
  245.                 }
  246.                 /* Process ACK */
  247.                 switch(tcb->state){
  248.                 case SYN_RECEIVED:
  249.                         if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  250.                                 update(tcb,&seg);
  251.                                 setstate(tcb,ESTABLISHED);
  252.                         } else {
  253.                                 free_p(bp);
  254.                                 reset(source,dest,tos,length,&seg);
  255.                                 return;
  256.                         }
  257.                         break;
  258.                 case ESTABLISHED:
  259.                 case CLOSE_WAIT:
  260.                         update(tcb,&seg);
  261.                         break;
  262.                 case FINWAIT1:  /* p. 73 */
  263.                         update(tcb,&seg);
  264.                         if(tcb->sndcnt == 0){
  265.                                 /* Our FIN is acknowledged */
  266.                                 setstate(tcb,FINWAIT2);
  267.                         }
  268.                         break;
  269.                 case FINWAIT2:
  270.                         update(tcb,&seg);
  271.                         break;
  272.                 case CLOSING:
  273.                         update(tcb,&seg);
  274.                         if(tcb->sndcnt == 0){
  275.                                 /* Our FIN is acknowledged */
  276.                                 setstate(tcb,TIME_WAIT);
  277.                                 tcb->timer.start = MSL2 * (1000 / MSPTICK);
  278.                                 start_timer(&tcb->timer);
  279.                         }
  280.                         break;
  281.                 case LAST_ACK:
  282.                         update(tcb,&seg);
  283.                         if(tcb->sndcnt == 0){
  284.                                 /* Our FIN is acknowledged, close connection */
  285.                                 close_self(tcb,NORMAL);
  286.                                 return;
  287.                         }                       
  288.                 case TIME_WAIT:
  289.                         tcb->flags |= FORCE;
  290.                         start_timer(&tcb->timer);
  291.                 }
  292.  
  293.                 /* (URGent bit processing skipped here) */
  294.  
  295.                 /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  296.                 if(length != 0){
  297.                         switch(tcb->state){
  298.                         case SYN_RECEIVED:
  299.                         case ESTABLISHED:
  300.                         case FINWAIT1:
  301.                         case FINWAIT2:
  302.                                 /* Place on receive queue */
  303.                                 append(&tcb->rcvq,bp);
  304.                                 tcb->rcvcnt += length;
  305.                                 tcb->rcv.nxt += length;
  306.                                 tcb->rcv.wnd -= length;
  307.                                 tcb->flags |= FORCE;
  308.                                 break;
  309.                         default:
  310.                                 /* Ignore segment text */
  311.                                 free_p(bp);
  312.                                 break;
  313.                         }
  314.                 }
  315.                 /* If the user has set up a r_upcall function and there's
  316.                  * data to be read, notify him.
  317.                  *
  318.                  * This is done before sending an acknowledgement,
  319.                  * to give the user a chance to piggyback some reply data.
  320.                  * It's also done before processing FIN so that the state
  321.                  * change upcall will occur after the user has had a chance
  322.                  * to read the last of the incoming data.
  323.                  */
  324.                 if(tcb->r_upcall && tcb->rcvcnt != 0){
  325.                         (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  326.                 }
  327.                 /* process FIN bit (p 75) */
  328.                 if(seg.flags & FIN){
  329.                         tcb->flags |= FORCE;    /* Always respond with an ACK */
  330.  
  331.                         switch(tcb->state){
  332.                         case SYN_RECEIVED:
  333.                         case ESTABLISHED:
  334.                                 tcb->rcv.nxt++;
  335.                                 setstate(tcb,CLOSE_WAIT);
  336.                                 break;
  337.                         case FINWAIT1:
  338.                                 tcb->rcv.nxt++;
  339.                                 if(tcb->sndcnt == 0){
  340.                                         /* Our FIN has been acked; bypass CLOSING state */
  341.                                         setstate(tcb,TIME_WAIT);
  342.                                         tcb->timer.start = MSL2 * (1000/MSPTICK);
  343.                                         start_timer(&tcb->timer);
  344.                                 } else {
  345.                                         setstate(tcb,CLOSING);
  346.                                 }
  347.                                 break;
  348.                         case FINWAIT2:
  349.                                 tcb->rcv.nxt++;
  350.                                 setstate(tcb,TIME_WAIT);
  351.                                 tcb->timer.start = MSL2 * (1000/MSPTICK);
  352.                                 start_timer(&tcb->timer);
  353.                                 break;
  354.                         case CLOSE_WAIT:
  355.                         case CLOSING:
  356.                         case LAST_ACK:
  357.                                 break;          /* Ignore */
  358.                         case TIME_WAIT: /* p 76 */
  359.                                 start_timer(&tcb->timer);
  360.                                 break;
  361.                         }
  362.                 }
  363.                 /* Scan the resequencing queue, looking for a segment we can handle,
  364.                  * and freeing all those that are now obsolete.
  365.                  */
  366.                 while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  367.                         get_reseq(tcb,&tos,&seg,&bp,&length);
  368.                         if(trim(tcb,&seg,&bp,&length) == 0)
  369.                                 goto gotone;
  370.                         /* Segment is an old one; trim has freed it */
  371.                 }
  372.                 break;
  373. gotone: ;
  374.         }
  375.         tcp_output(tcb);        /* Send any necessary ack */
  376. }
  377.  
  378. /* Process an incoming ICMP response */
  379. void tcp_icmp(int32 source, int32 dest, char type, char code, struct mbuf **bpp)
  380. {
  381.         struct tcp seg;
  382.         struct connection conn;
  383.         register struct tcb *tcb;
  384.  
  385.         /* Extract the socket info from the returned TCP header fragment
  386.          * Note that since this is a datagram we sent, the source fields
  387.          * refer to the local side.
  388.          */
  389.         ntohtcp(&seg,bpp);
  390.         conn.local.port = seg.source;
  391.         conn.remote.port = seg.dest;
  392.         conn.local.address = source;
  393.         conn.remote.address = dest;
  394.         if((tcb = lookup_tcb(&conn)) == NULLTCB)
  395.                 return; /* Unknown connection, ignore */
  396.  
  397.         /* Verify that the sequence number in the returned segment corresponds
  398.          * to something currently unacknowledged. If not, it can safely
  399.          * be ignored.
  400.          */
  401.         if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  402.                 return;
  403.  
  404.         /* The strategy here is that Destination Unreachable and Time Exceeded
  405.          * messages that occur after a connection has been established are likely
  406.          * to be transient events, and shouldn't kill our connection (at least
  407.          * until after we've tried a few more times). On the other hand, if
  408.          * they occur on our very first attempt to send a datagram on a new
  409.          * connection, they're probably "for real". In any event, the info
  410.          * is saved.
  411.          */
  412.         switch(uchar(type)){
  413.         case DEST_UNREACH:
  414.         case TIME_EXCEED:
  415.                 tcb->type = type;
  416.                 tcb->code = code;
  417.                 if(tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED){
  418.                         close_self(tcb,NETWORK);
  419.                 }
  420.                 break;
  421.         case QUENCH:
  422.                 /* Source quench; cut the congestion window in half,
  423.                  * but don't let it go below one packet
  424.                  */
  425.                 tcb->cwind /= 2;
  426.                 tcb->cwind = max(tcb->mss,tcb->cwind);
  427.                 break;
  428.         }
  429. }
  430. /* Send an acceptable reset (RST) response for this segment
  431.  * The RST reply is composed in place on the input segment
  432.  */
  433. static void reset(int32 source, int32 dest,char tos, int16 length,
  434.                   register struct tcp *seg)
  435. {
  436.         struct mbuf *hbp;
  437.         struct pseudo_header ph;
  438.         int16 tmp;
  439.         char rflags;
  440.  
  441.         if(seg->flags & RST)
  442.                 return; /* Never send an RST in response to an RST */
  443.  
  444.         tcp_stat.resets++;
  445.  
  446.         /* Compose the RST IP pseudo-header, swapping addresses */
  447.         ph.source = dest;
  448.         ph.dest = source;
  449.         ph.protocol = TCP_PTCL;
  450.         ph.length = TCPLEN;
  451.  
  452.         /* Swap port numbers */
  453.         tmp = seg->dest;
  454.         seg->dest = seg->source;
  455.         seg->source = tmp;
  456.  
  457.         rflags = RST;
  458.         if(seg->flags & ACK){
  459.                 /* This reset is being sent to clear a half-open connection.
  460.                  * Set the sequence number of the RST to the incoming ACK
  461.                  * so it will be acceptable.
  462.                  */
  463.                 seg->seq = seg->ack;
  464.                 seg->ack = 0;
  465.         } else {
  466.                 /* We're rejecting a connect request (SYN) from LISTEN state
  467.                  * so we have to "acknowledge" their SYN.
  468.                  */
  469.                 rflags |= ACK;
  470.                 seg->ack = seg->seq;
  471.                 seg->seq = 0;
  472.                 if(seg->flags & SYN)
  473.                         seg->ack++;
  474.                 seg->ack += length;
  475.                 if(seg->flags & FIN)
  476.                         seg->ack++;
  477.         }
  478.         seg->flags = rflags;
  479.         seg->wnd = 0;
  480.         seg->up = 0;
  481.         seg->mss = 0;
  482.         if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  483.                 return;
  484.         /* Ship it out (note swap of addresses) */
  485.         ip_send(dest,source,TCP_PTCL,tos,0,hbp,ph.length,0,0);
  486. }
  487.  
  488. /* Process an incoming acknowledgement and window indication.
  489.  * From page 72.
  490.  */
  491. static void update(register struct tcb *tcb, register struct tcp *seg)
  492. {
  493.         int16 acked;
  494.         int16 expand;
  495.  
  496.         acked = 0;
  497.         if(seq_gt(seg->ack,tcb->snd.nxt)){
  498.                 tcb->flags |= FORCE;    /* Acks something not yet sent */
  499.                 return;
  500.         }
  501.         /* Decide if we need to do a window update.
  502.          * This is always checked whenever a legal ACK is received,
  503.          * even if it doesn't actually acknowledge anything,
  504.          * because it might be a spontaneous window reopening.
  505.          */
  506.         if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1) 
  507.          && seq_ge(seg->ack,tcb->snd.wl2))){
  508.                 /* If the window had been closed, crank back the
  509.                  * send pointer so we'll immediately resume transmission.
  510.                  * Otherwise we'd have to wait until the next probe.
  511.                  */
  512.                 if(tcb->snd.wnd == 0 && seg->wnd != 0)
  513.                         tcb->snd.ptr = tcb->snd.una;
  514.                 tcb->snd.wnd = seg->wnd;
  515.                 tcb->snd.wl1 = seg->seq;
  516.                 tcb->snd.wl2 = seg->ack;
  517.         }
  518.         /* See if anything new is being acknowledged */
  519.         if(!seq_gt(seg->ack,tcb->snd.una))
  520.                 return; /* Nothing more to do */
  521.  
  522.         /* We're here, so the ACK must have actually acked something */
  523.         acked = (int16)(seg->ack - tcb->snd.una);
  524.  
  525.         /* Expand congestion window if not already at limit */
  526.         if(tcb->cwind < tcb->snd.wnd){
  527.                 if(tcb->cwind < tcb->ssthresh){
  528.                         /* Still doing slow start/CUTE, expand by amount acked */
  529.                         expand = min(acked,tcb->mss);
  530.                 } else {
  531.                         /* Steady-state test of extra path capacity */
  532.                         expand = (int16)((long)tcb->mss * tcb->mss) / tcb->cwind;
  533.                 }
  534.                 /* Guard against arithmetic overflow */
  535.                 if(tcb->cwind + expand < tcb->cwind)
  536.                         expand = MAXINT16 - tcb->cwind;
  537.  
  538.                 /* Don't expand beyond the offered window */
  539.                 if(tcb->cwind + expand > tcb->snd.wnd)
  540.                         expand = tcb->snd.wnd - tcb->cwind;
  541.  
  542.                 if(expand != 0){
  543. #ifdef  notdef
  544.                         /* Kick up the mean deviation estimate to prevent
  545.                          * unnecessary retransmission should we already be
  546.                          * bandwidth limited
  547.                          */
  548.                         tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  549. #endif
  550.                         tcb->cwind += expand;
  551.                 }
  552.         }
  553.         /* Round trip time estimation */
  554.         if(run_timer(&tcb->rtt_timer) && seq_ge(seg->ack,tcb->rttseq)){
  555.                 /* A timed sequence number has been acked */
  556.                 stop_timer(&tcb->rtt_timer);
  557.                 if(!(tcb->flags & RETRAN)){
  558.                         int32 rtt;      /* measured round trip time */
  559.                         int32 abserr;   /* abs(rtt - srtt) */
  560.  
  561.                         /* This packet was sent only once and now
  562.                          * it's been acked, so process the round trip time
  563.                          */
  564.                         rtt = tcb->rtt_timer.start - tcb->rtt_timer.count;
  565.                         rtt *= MSPTICK;         /* milliseconds */
  566.  
  567.                         /* If this ACKs our SYN, this is the first ACK
  568.                          * we've received; base our entire SRTT estimate
  569.                          * on it. Otherwise average it in with the prior
  570.                          * history, also computing mean deviation.
  571.                          */
  572.                         if(rtt > tcb->srtt &&
  573.                          (tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED)){
  574.                                 tcb->srtt = rtt;
  575.                         } else {
  576.                                 abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  577.                                 tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt) / AGAIN;
  578.                                 tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr) / DGAIN;
  579.                         }
  580.                         /* Reset the backoff level */
  581.                         tcb->backoff = 0;
  582.                 }
  583.         }
  584.         /* If we're waiting for an ack of our SYN, note it and adjust count */
  585.         if(!(tcb->flags & SYNACK)){
  586.                 tcb->flags |= SYNACK;
  587.                 acked--;
  588.                 tcb->sndcnt--;
  589.         }
  590.         /* Remove acknowledged bytes from the send queue and update the
  591.          * unacknowledged pointer. If a FIN is being acked,
  592.          * pullup won't be able to remove it from the queue.
  593.          */
  594.         pullup(&tcb->sndq,NULLCHAR,acked);
  595.  
  596.         /* This will include the FIN if there is one */
  597.         tcb->sndcnt -= acked;
  598.         tcb->snd.una = seg->ack;
  599.  
  600.         /* Stop retransmission timer, but restart it if there is still
  601.          * unacknowledged data.
  602.          */     
  603.         stop_timer(&tcb->timer);
  604.         if(tcb->snd.una != tcb->snd.nxt)
  605.                 start_timer(&tcb->timer);
  606.  
  607.         /* If retransmissions have been occurring, make sure the
  608.          * send pointer doesn't repeat ancient history
  609.          */
  610.         if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  611.                 tcb->snd.ptr = tcb->snd.una;
  612.  
  613.         /* Clear the retransmission flag since the oldest
  614.          * unacknowledged segment (the only one that is ever retransmitted)
  615.          * has now been acked.
  616.          */
  617.         tcb->flags &= ~RETRAN;
  618.  
  619.         /* If outgoing data was acked, notify the user so he can send more
  620.          * unless we've already sent a FIN.
  621.          */
  622.         if(acked != 0 && tcb->t_upcall){
  623.                 switch(tcb->state){
  624.                 case ESTABLISHED:
  625.                 case CLOSE_WAIT:
  626.                         (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  627.                 }
  628.         }
  629. }
  630.  
  631. /* Determine if the given sequence number is in our receiver window.
  632.  * NB: must not be used when window is closed!
  633.  */
  634. static int in_window(struct tcb *tcb, int32 seq)
  635. {
  636.         return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  637. }
  638.  
  639. /* Process an incoming SYN */
  640. static void proc_syn(register struct tcb *tcb, char tos, struct tcp *seg)
  641. {
  642.         int16 mtu;
  643.  
  644.         tcb->flags |= FORCE;    /* Always send a response */
  645.  
  646.         /* Note: It's not specified in RFC 793, but SND.WL1 and
  647.          * SND.WND are initialized here since it's possible for the
  648.          * window update routine in update() to fail depending on the
  649.          * IRS if they are left unitialized.
  650.          */
  651.         /* Check incoming precedence and increase if higher */
  652.         if(PREC(tos) > PREC(tcb->tos))
  653.                 tcb->tos = tos;
  654.         tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  655.         tcb->snd.wl1 = tcb->irs = seg->seq;
  656.         tcb->snd.wnd = seg->wnd;
  657.         if(seg->mss != 0)
  658.                 tcb->mss = seg->mss;
  659.         /* Check the MTU of the interface we'll use to reach this guy
  660.          * and lower the MSS so that unnecessary fragmentation won't occur
  661.          */
  662.         if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  663.                 /* Allow space for the TCP and IP headers */
  664.                 mtu -= TCPLEN + IPLEN;
  665.                 tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  666.         }
  667. }
  668.  
  669. /* Generate an initial sequence number and put a SYN on the send queue */
  670. void send_syn(register struct tcb *tcb)
  671. {
  672.         tcb->iss = iss();
  673.         tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  674.         tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  675.         tcb->sndcnt++;
  676.         tcb->flags |= FORCE;
  677. }
  678.  
  679. /* Add an entry to the resequencing queue in the proper place */
  680. static void add_reseq(struct tcb *tcb, char tos, struct tcp *seg,
  681.                       struct mbuf *bp, int16 length)
  682. {
  683.         register struct reseq *rp,*rp1;
  684.  
  685.         /* Allocate reassembly descriptor */
  686.         if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  687.                 /* No space, toss on floor */
  688.                 free_p(bp);
  689.                 return;
  690.         }
  691.         rp->seg = *seg;
  692.         rp->tos = tos;
  693.         rp->bp = bp;
  694.         rp->length = length;
  695.  
  696.         /* Place on reassembly list sorting by starting seq number */
  697.         rp1 = tcb->reseq;
  698.         if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  699.                 /* Either the list is empty, or we're less than all other
  700.                  * entries; insert at beginning.
  701.                  */
  702.                 rp->next = rp1;
  703.                 tcb->reseq = rp;
  704.         } else {
  705.                 /* Find the last entry less than us */
  706.                 for(;;){
  707.                         if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  708.                                 /* We belong just after this one */
  709.                                 rp->next = rp1->next;
  710.                                 rp1->next = rp;
  711.                                 break;
  712.                         }
  713.                         rp1 = rp1->next;
  714.                 }
  715.         }
  716. }
  717.  
  718. /* Fetch the first entry off the resequencing queue */
  719. static void get_reseq(register struct tcb *tcb, char *tos,
  720.                       struct tcp *seg, struct mbuf **bp, int16 *length)
  721. {
  722.         register struct reseq *rp;
  723.  
  724.         if((rp = tcb->reseq) == NULLRESEQ)
  725.                 return;
  726.  
  727.         tcb->reseq = rp->next;
  728.  
  729.         *tos = rp->tos;
  730.         *seg = rp->seg;
  731.         *bp = rp->bp;
  732.         *length = rp->length;
  733.         free((char *)rp);
  734. }
  735.  
  736. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  737.  * unacceptable.
  738.  */
  739. static int trim(register struct tcb *tcb, register struct tcp *seg,
  740.                 struct mbuf **bp, int16 *length)
  741. {
  742.         struct mbuf *nbp;
  743.         int dupcnt,excess;
  744.         int16 len;              /* Segment length including flags */
  745.         char accept;
  746.  
  747.         accept = 0;
  748.         len = *length;
  749.         if(seg->flags & SYN)
  750.                 len++;
  751.         if(seg->flags & FIN)
  752.                 len++;
  753.  
  754.         /* Acceptability tests */
  755.         if(tcb->rcv.wnd == 0){
  756.                 /* Only in-order, zero-length segments are acceptable when our window
  757.                  * is closed.
  758.                  */
  759.                 if(seg->seq == tcb->rcv.nxt && len == 0){
  760.                         return 0;       /* Acceptable, no trimming needed */
  761.                 }
  762.         } else {
  763.                 /* Some part of the segment must be in the window */
  764.                 if(in_window(tcb,seg->seq)){
  765.                         accept++;       /* Beginning is */
  766.                 } else if(len != 0){
  767.                         if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  768.                          seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  769.                                 accept++;
  770.                         }
  771.                 }
  772.         }
  773.         if(!accept){
  774.                 free_p(*bp);
  775.                 return -1;
  776.         }
  777.         dupcnt = tcb->rcv.nxt - seg->seq;
  778.         if(dupcnt > 0){
  779.                 tcb->rerecv += dupcnt;
  780.                 /* Trim off SYN if present */
  781.                 if(seg->flags & SYN){
  782.                         /* SYN is before first data byte */
  783.                         seg->flags &= ~SYN;
  784.                         seg->seq++;
  785.                         dupcnt--;
  786.                 }
  787.                 if(dupcnt > 0){
  788.                         pullup(bp,NULLCHAR,(int16)dupcnt);
  789.                         seg->seq += dupcnt;
  790.                         *length -= (int16)dupcnt;
  791.                 }
  792.         }
  793.         excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd);
  794.         if(excess > 0){
  795.                 tcb->rerecv += excess;
  796.                 /* Trim right edge */
  797.                 *length -= (int16)excess;
  798.                 nbp = copy_p(*bp,*length);
  799.                 free_p(*bp);
  800.                 *bp = nbp;
  801.                 seg->flags &= ~FIN;     /* FIN follows last data byte */
  802.         }
  803.         return 0;
  804. }
  805.